package Parser;

import java.util.Vector;

/**
 * Title: Universe
 * Description: Parses the universes from knowlegde base file
 * @version 1.0
 */

public class Universe {
  private String Name, UniverseText, SetText, KBError;
  private Vector vecSet;

  private boolean KBSet = true;

  public Universe(String name) {
    this.Name = name;
    vecSet = new Vector();
  }

  public void RetrieveSets(String SetText){
    int UBegin = 0, UEnd = 0;
    String CurrentSet;

    //first set
    try{
      UBegin = SetText.indexOf("SET") + 3;
      this.KBSet = true;
    } catch(Exception e) {
      this.KBError = "No sets defined";
    }

    if(this.KBSet == true){
      try {
        UEnd = SetText.indexOf("SET_END");
        this.KBSet = false;
      }
      catch (Exception e) {
        this.KBError = "No end of set defined";
      }
    }

    if (UBegin < 0 || UEnd < UBegin) return;
    CurrentSet = SetText.substring(UBegin, UEnd);

    while (UEnd < SetText.length()) {
        //reading all the other sets
        try{
          UBegin = SetText.indexOf("SET",UEnd+7) + 3;
          this.KBSet = true;
        }
        catch (Exception e) {
          this.KBError = "No sets defined";
        }

        if (this.KBSet == true) {
          try {
            UEnd = SetText.indexOf("SET_END",UEnd+7);
            this.KBSet = false;
          }
          catch (Exception e) {
            this.KBError = "No end of set defined";
          }
        }

        this.extractSet(CurrentSet);

        if (UBegin < 0 || UEnd < UBegin) return;
        CurrentSet = SetText.substring(UBegin, UEnd);
    }
  }

  private void addSet(String name, double x1, double x2, double x3, double x4){
    Set tmpSet = new Set(name, x1, x2, x3, x4);
    this.vecSet.addElement(tmpSet);
  }

  private void extractSet(String set){
    double x1=-1, x2=-1, x3=-1, x4=-1;
    String name = "";

    //nu proberen de naam en x-waarden te extracten
    try {
      name = getWord(set, 0);
      x1 = Double.parseDouble(getWord(set, 1));
      x2 = Double.parseDouble(getWord(set, 2));
      x3 = Double.parseDouble(getWord(set, 3));
      x4 = Double.parseDouble(getWord(set, 4));
    }  catch (Exception e) {
      System.out.println("Exception occured while parsing SET:\n" + set +
                         "\nError:\n" + e.getMessage());
      System.exit( -1);
    }

    //alle info is er, nu aanmaken nieuwe set en toevoegen aan setVector van huidige Universe
    try {
      this.addSet(name, x1, x2, x3, x4);
    } catch (Exception e) {
      System.out.println("Exception occured while adding new SET:\n" +
                         set + "\nError:\n" + e.getMessage());
      System.exit( -1);
    }
  }

  private String getWord(String setstr, int nr) {
    int currentWord = 0;
    int i = 0;

    //remove starting and ending spaces etc..
    setstr = setstr.trim();

    while(setstr.length() > 0) {
      if(i == setstr.length() || setstr.charAt(i) == '\n' || setstr.charAt(i) == ' ' || setstr.charAt(i) == '\t') {
        //einde van huidige woord gevonden
        if(nr == currentWord) {  //huidige woord moet worden teruggegeven
          return (setstr.substring(0, i)).trim();
        }
        //nog niet het goede woord, doorgaan met volgende woord zoeken
        setstr = (setstr.substring(i, setstr.length())).trim();
        i=0;
        currentWord++;
      }
      i++;
    }
    return null;
  }

  public void SetText(String UniverseText){
    this.RetrieveSets(UniverseText);
  }

  public String getName(){
    return this.Name;
  }

  public String toString(){
    String Universum;
    //eerst naam invoegen
    Universum = this.Name + "\n";

    for (int i = 0; i < vecSet.size(); i++) {
      Universum = Universum + ( (Set) vecSet.get(i)).toString();
    }

    System.out.println(Universum);
    return Universum;
  }

  public Set getSet(int index)
  {
    return (Set) vecSet.elementAt(index);
  }

  public Set getSet(String setname)
  {
    for(int a = 0; a < vecSet.size(); a++)
    {
      Set tmpSet = (Set) vecSet.elementAt(a);
      if(tmpSet.GetName().equals(setname))
      {
        return getSet(a);
      }
    }
    return null;
  }

  public int getSetCount()
  {
        return vecSet.size();
  }

}
